﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PServiceBus.Core.Interface;
using PServiceBus.Core.Runtime.Messages;
using PServiceBus.Services.Gateway.Runtime;
using PServiceBus.Core.Runtime;

namespace PServiceBus.MessageStores {
    public class MessageStoreNotification : IMessageStore {

        const string FAILED_MESSAGE_TOPIC = "PSBMessageFailed",
            RETRY_MESSAGE_TOPIC = "PSBMessageRetry",
            SENT_MESSAGE_TOPIC = "PSBMessageSent";
        private static readonly Dictionary<MessageType, string> _messageTypeMap =
            new Dictionary<MessageType, string>();

        #region IMessageStore Members

        public void Store(PublishedMessage message) {
            var msg = message.Message;
            var name = message.Responses.Any(x => !x.TransportResponse.Success)
                ? FAILED_MESSAGE_TOPIC : _messageTypeMap[message.Type];
            Publish(name, new TopicNotification {
                CreateDate = msg.CreateDate.ToString("MM/dd/yyyy hh:mm:ss tt"),
                Name = msg.TopicName, ID = message.ID.ToString(), Type = message.Type.ToString() });
        }

        public void Init() {
            RegisterTopic(FAILED_MESSAGE_TOPIC);
            RegisterTopic(RETRY_MESSAGE_TOPIC);
            RegisterTopic(SENT_MESSAGE_TOPIC);
            SetupMap();
        }

        private void SetupMap() {
            _messageTypeMap[MessageType.New] = SENT_MESSAGE_TOPIC;
            _messageTypeMap[MessageType.Retry] = RETRY_MESSAGE_TOPIC;
        }

        private void Publish(string name, TopicNotification message) {
            var topicName = message.Name;
            if (topicName == FAILED_MESSAGE_TOPIC ||
                topicName == SENT_MESSAGE_TOPIC || topicName == RETRY_MESSAGE_TOPIC) return;
            Topic.Select(name).Publish(message);
        }

        private void RegisterTopic(string name) {
            if (!Topic.Exists(name)) Topic.Register(name);
        }

        public string Address { get; set; }

        #endregion
    }
}
